<template>
  <!-- 新增/修改 -->
  <el-dialog
    v-model="dialogVisible"
    :title="formData.id === undefined ? '新增菜单按钮' : '修改菜单按钮'"
    @closed="closedDialog"
    width="40%"
    :close-on-click-modal="false"
  >
    <el-form
      ref="formRef"
      :model="formData"
      :rules="formRules"
      label-width="100px"
      label-position="right"
      v-loading="formLoading"
    >
      <el-form-item label="按钮标题" prop="buttonTitle">
        <el-input v-model="formData.buttonTitle" placeholder="请输入按钮标题" />
      </el-form-item>
      <el-form-item label="按钮编码" prop="buttonCode">
        <el-input v-model="formData.buttonCode" placeholder="请输入按钮编码" />
      </el-form-item>
      <el-form-item label="请求方式" prop="method">
        <el-select v-model="formData.method" placeholder="请选择请求方式">
          <el-option
            v-for="item in METHOD_OPTIONS"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="请求地址" prop="url">
        <el-input v-model="formData.url" placeholder="请输入请求地址" />
      </el-form-item>
      <el-form-item label="菜单描述" prop="description">
        <el-input
          type="textarea"
          v-model="formData.description"
          placeholder="请输入菜单描述"
          maxlength="500"
          show-word-limit
          :rows="4"
        />
      </el-form-item>
    </el-form>

    <template #footer>
      <el-popover
        placement="bottom"
        title="匹配说明"
        width="300"
        trigger="hover"
      >
        <div>
          <ul>
            <li>? 匹配一个字符</li>
            <li>* 匹配0个或多个字符</li>
            <li>** 匹配0个或多个目录</li>
          </ul>
        </div>
        <template #reference>
          <el-button slot="reference" type="info" :icon="WarningFilled">
            帮助
          </el-button>
        </template>
      </el-popover>
      <el-button @click="closedDialog">取消</el-button>
      <el-button
        type="primary"
        @click="handleCreateOrUpdate"
        :loading="loading"
      >
        确认
      </el-button>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, onBeforeMount } from "vue";
import MenuButtonAPI, { type MenuButtonVO } from "@/api/system/sys/menuButton";
import { type FormInstance, type FormRules } from "element-plus";
import { cloneDeep } from "lodash-es";
import { METHOD_OPTIONS } from "./const";
import { WarningFilled } from "@element-plus/icons-vue";

/**
 * 菜单按钮详情页面
 */
defineOptions({
  name: "EditMenuButtonDetailsDialog",
});
const props = defineProps({
  menuButtonId: {
    type: Number,
    required: false,
  },
  menuId: {
    type: String,
    required: false,
  },
  closedDialog: {
    type: Function,
    required: true,
  },
});

/** 表单初始化 */
const DEFAULT_FORM_DATA: MenuButtonVO = {
  id: props.menuButtonId,
  menuId: props.menuId,
  /** 按钮编码 */
  buttonCode: undefined,
  /** 按钮标题 */
  buttonTitle: undefined,
  /** 请求地址 */
  url: undefined,
  /** 请求方式（POST|GET|DELETE|PUT） */
  method: undefined,
  /** 菜单描述 */
  description: undefined,
};
/** 表单对象 */
const formData = ref<MenuButtonVO>(cloneDeep(DEFAULT_FORM_DATA));
const formRef = ref<FormInstance | null>(null);
/** 表单校验格式 */
const formRules: FormRules<MenuButtonVO> = {
  buttonCode: [
    {
      required: true,
      message: "请输入按钮编码",
      trigger: "blur",
    },
    {
      min: 1,
      max: 128,
      message: "长度在128以内个字符",
      trigger: "blur",
    },
  ],
  buttonTitle: [
    {
      required: true,
      message: "请输入按钮标题",
      trigger: "blur",
    },
    {
      min: 1,
      max: 64,
      message: "长度在64以内个字符",
      trigger: "blur",
    },
  ],
  url: [
    {
      required: true,
      message: "请输入请求地址",
      trigger: "blur",
    },
    {
      min: 1,
      max: 256,
      message: "长度在256以内个字符",
      trigger: "blur",
    },
  ],
  method: [
    {
      required: true,
      message: "请选择请求方式（POST|GET|DELETE|PUT）",
      trigger: "blur",
    },
    {
      message: "请选择请求方式",
      trigger: "blur",
    },
  ],
  description: [
    {
      required: false,
      message: "请输入菜单描述",
      trigger: "blur",
    },
    {
      min: 1,
      max: 500,
      message: "长度在500以内个字符",
      trigger: "blur",
    },
  ],
};

const dialogVisible = ref<boolean>(true);
const loading = ref<boolean>(false);
const formLoading = ref<boolean>(false);

/** 新增或者更新 */
const handleCreateOrUpdate = () => {
  formRef.value?.validate((valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields);

    loading.value = true;
    if (formData.value.id === undefined) {
      // 新增
      MenuButtonAPI.addSysMenuButtonApi(formData.value)
        .then(() => {
          ElMessage.success("操作成功");
        })
        .finally(() => {
          loading.value = false;
          props.closedDialog(props.menuId);
        });
    } else {
      // 更新
      MenuButtonAPI.putSysMenuButtonApi(formData.value.id, formData.value)
        .then(() => {
          ElMessage.success("操作成功");
        })
        .finally(() => {
          loading.value = false;
          props.closedDialog(props.menuId);
        });
    }
  });
};

/** 关闭弹窗 */
const closedDialog = () => {
  props.closedDialog(false);
};

/** 页面渲染完成后初始化 */
onBeforeMount(async () => {
  if (props.menuButtonId) {
    formLoading.value = true;
    MenuButtonAPI.getSysMenuButtonApi(props.menuButtonId)
      .then((res) => {
        const { data } = res;
        formData.value = data;
      })
      .finally(() => {
        formLoading.value = false;
      });
  }
});
</script>

<style lang="scss" scoped></style>
